/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.trick.admin.node;

import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;

/**
 *
 * @author takahara
 */
public class CodeEditor extends StackPane {

    /**
     * a webview used to encapsulate the CodeMirror JavaScript.
     */
    final WebView webview = new WebView();
    /**
     * a snapshot of the code to be edited kept for easy initilization and
     * reversion of editable code.
     */
    private String editingCode;
    /**
     * a template for editing code - this can be changed to any template derived
     * from the supported modes at http://codemirror.net to allow syntax
     * highlighted editing of a wide variety of languages.
     */
    private final String editingTemplate =
            "<!doctype html>"
            + "<html>"
            + "<head>"
            + "  <link rel=\"stylesheet\" href=\"http://codemirror.net/lib/codemirror.css\">"
            + "  <script src=\"http://codemirror.net/lib/codemirror.js\"></script>"
            + "  <script src=\"http://codemirror.net/mode/css/css.js\"></script>"
            + "  <script src=\"http://codemirror.net/mode/javascript/javascript.js\"></script>"
            + "  <script src=\"http://codemirror.net/mode/xml/xml.js\"></script>"
            + "  <script src=\"http://codemirror.net/mode/htmlmixed/htmlmixed.js\"></script>"
            + "</head>"
            + "<body>"
            + "<form><textarea id=\"code\" name=\"code\" style=\"font-size:14px;\">\n"
            + "${code}"
            + "</textarea></form>"
            + "<script>"
            + "  var editor = CodeMirror.fromTextArea(document.getElementById(\"code\"), {"
            + "    lineNumbers: true,"
            + "    matchBrackets: true,"
            + "    mode: \"text/html\""
//            + "    mode: \"text/html\","
//            + "    theme: \"default\","
//            + "    indentUnit: 4,"
//            + "    indentWithTabs: false,"
//            + "    tabMode: \"shift\","
//            + "    electricChars: false,"
//            + "    lineNumbers: true,"
//            + "    firstLineNumber: 1,"
//            + "    gutter: false,"
//            + "    fixedGutter:false,"
//            + "    matchBrackets: true"
            + "  });"
            + "</script>"
            + "</body>"
            + "</html>";


    /**
     * applies the editing template to the editing code to create the
     * html+javascript source for a code editor.
     */
    private String applyEditingTemplate() {
        return editingTemplate.replace("${code}", editingCode);
    }

    /**
     * sets the current code in the editor and creates an editing snapshot of
     * the code which can be reverted to.
     */
    public void setCode(String newCode) {
        this.editingCode = newCode;
        webview.getEngine().loadContent(applyEditingTemplate());
    }

    /**
     * returns the current code in the editor and updates an editing snapshot of
     * the code which can be reverted to.
     */
    public String getCodeAndSnapshot() {
        this.editingCode = (String) webview.getEngine().executeScript("editor.getValue();");
        return editingCode;
    }

    /**
     * revert edits of the code to the last edit snapshot taken.
     */
    public void revertEdits() {
        setCode(editingCode);
    }

    /**
     * Create a new code editor.
     *
     * @param editingCode the initial code to be edited in the code editor.
     */
    CodeEditor(String editingCode) {
        this.editingCode = editingCode;

        webview.setPrefSize(650, 325);
        webview.setMinSize(650, 325);
        webview.getEngine().loadContent(applyEditingTemplate());

        this.getChildren().add(webview);
    }
}
